home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / ATTRIB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-24  |  22.7 KB  |  677 lines

  1. /* $Id: attrib.c,v 3.5 1998/08/23 22:18:49 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: attrib.c,v $
  26.  * Revision 3.5  1998/08/23 22:18:49  brianp
  27.  * added Driver.Viewport and Driver.DepthRange function pointers
  28.  *
  29.  * Revision 3.4  1998/07/29 04:09:52  brianp
  30.  * save/restore of texture state was incomplete
  31.  *
  32.  * Revision 3.3  1998/02/20 04:50:09  brianp
  33.  * implemented GL_SGIS_multitexture
  34.  *
  35.  * Revision 3.2  1998/02/08 20:16:50  brianp
  36.  * removed unneeded headers
  37.  *
  38.  * Revision 3.1  1998/02/01 16:37:19  brianp
  39.  * added GL_EXT_rescale_normal extension
  40.  *
  41.  * Revision 3.0  1998/01/31 20:44:48  brianp
  42.  * initial rev
  43.  *
  44.  */
  45.  
  46.  
  47. #ifdef PC_HEADER
  48. #include "all.h"
  49. #else
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include "attrib.h"
  53. #include "context.h"
  54. #include "macros.h"
  55. #include "misc.h"
  56. #include "types.h"
  57. #endif
  58.  
  59.  
  60. #define MALLOC_STRUCT(T)  (struct T *) malloc( sizeof(struct T) )
  61.  
  62.  
  63.  
  64. static struct gl_attrib_node *new_attrib_node( GLbitfield kind )
  65. {
  66.    struct gl_attrib_node *an;
  67.  
  68.    an = (struct gl_attrib_node *) malloc( sizeof(struct gl_attrib_node) );
  69.    if (an) {
  70.       an->kind = kind;
  71.    }
  72.    return an;
  73. }
  74.  
  75.  
  76.  
  77. void gl_PushAttrib( GLcontext* ctx, GLbitfield mask )
  78. {
  79.    struct gl_attrib_node *newnode;
  80.    struct gl_attrib_node *head;
  81.  
  82.    if (INSIDE_BEGIN_END(ctx)) {
  83.       gl_error( ctx, GL_INVALID_OPERATION, "glPushAttrib" );
  84.       return;
  85.    }
  86.  
  87.    if (ctx->AttribStackDepth>=MAX_ATTRIB_STACK_DEPTH) {
  88.       gl_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
  89.       return;
  90.    }
  91.  
  92.    /* Build linked list of attribute nodes which save all attribute */
  93.    /* groups specified by the mask. */
  94.    head = NULL;
  95.  
  96.    if (mask & GL_ACCUM_BUFFER_BIT) {
  97.       struct gl_accum_attrib *attr;
  98.  
  99.       attr = MALLOC_STRUCT( gl_accum_attrib );
  100.       MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
  101.       newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
  102.       newnode->data = attr;
  103.       newnode->next = head;
  104.       head = newnode;
  105.    }
  106.  
  107.    if (mask & GL_COLOR_BUFFER_BIT) {
  108.       struct gl_colorbuffer_attrib *attr;
  109.       attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
  110.       MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
  111.       newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
  112.       newnode->data = attr;
  113.       newnode->next = head;
  114.       head = newnode;
  115.    }
  116.  
  117.    if (mask & GL_CURRENT_BIT) {
  118.       struct gl_current_attrib *attr;
  119.       attr = MALLOC_STRUCT( gl_current_attrib );
  120.       MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
  121.       newnode = new_attrib_node( GL_CURRENT_BIT );
  122.       newnode->data = attr;
  123.       newnode->next = head;
  124.       head = newnode;
  125.    }
  126.  
  127.    if (mask & GL_DEPTH_BUFFER_BIT) {
  128.       struct gl_depthbuffer_attrib *attr;
  129.       attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
  130.       MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
  131.       newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
  132.       newnode->data = attr;
  133.       newnode->next = head;
  134.       head = newnode;
  135.    }
  136.  
  137.    if (mask & GL_ENABLE_BIT) {
  138.       struct gl_enable_attrib *attr;
  139.       GLuint i;
  140.       attr = MALLOC_STRUCT( gl_enable_attrib );
  141.       /* Copy enable flags from all other attributes into the enable struct. */
  142.       attr->AlphaTest = ctx->Color.AlphaEnabled;
  143.       attr->AutoNormal = ctx->Eval.AutoNormal;
  144.       attr->Blend = ctx->Color.BlendEnabled;
  145.       for (i=0;i<MAX_CLIP_PLANES;i++) {
  146.          attr->ClipPlane[i] = ctx->Transform.ClipEnabled[i];
  147.       }
  148.       attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
  149.       attr->CullFace = ctx->Polygon.CullFlag;
  150.       attr->DepthTest = ctx->Depth.Test;
  151.       attr->Dither = ctx->Color.DitherFlag;
  152.       attr->Fog = ctx->Fog.Enabled;
  153.       for (i=0;i<MAX_LIGHTS;i++) {
  154.          attr->Light[i] = ctx->Light.Light[i].Enabled;
  155.       }
  156.       attr->Lighting = ctx->Light.Enabled;
  157.       attr->LineSmooth = ctx->Line.SmoothFlag;
  158.       attr->LineStipple = ctx->Line.StippleFlag;
  159.       attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
  160.       attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
  161.       attr->Map1Color4 = ctx->Eval.Map1Color4;
  162.       attr->Map1Index = ctx->Eval.Map1Index;
  163.       attr->Map1Normal = ctx->Eval.Map1Normal;
  164.       attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
  165.       attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
  166.       attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
  167.       attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
  168.       attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
  169.       attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
  170.       attr->Map2Color4 = ctx->Eval.Map2Color4;
  171.       attr->Map2Index = ctx->Eval.Map2Index;
  172.       attr->Map2Normal = ctx->Eval.Map2Normal;
  173.       attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
  174.       attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
  175.       attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
  176.       attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
  177.       attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
  178.       attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
  179.       attr->Normalize = ctx->Transform.Normalize;
  180.       attr->PointSmooth = ctx->Point.SmoothFlag;
  181.       attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
  182.       attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
  183.       attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
  184.       attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
  185.       attr->PolygonStipple = ctx->Polygon.StippleFlag;
  186.       attr->RescaleNormals = ctx->Transform.RescaleNormals;
  187.       attr->Scissor = ctx->Scissor.Enabled;
  188.       attr->Stencil = ctx->Stencil.Enabled;
  189.       attr->Texture = ctx->Texture.Enabled;
  190.       for (i=0; i<MAX_TEX_SETS; i++) {
  191.          attr->TexGen[i] = ctx->Texture.Set[i].TexGenEnabled;
  192.       }
  193.       newnode = new_attrib_node( GL_ENABLE_BIT );
  194.       newnode->data = attr;
  195.       newnode->next = head;
  196.       head = newnode;
  197.    }
  198.  
  199.    if (mask & GL_EVAL_BIT) {
  200.       struct gl_eval_attrib *attr;
  201.       attr = MALLOC_STRUCT( gl_eval_attrib );
  202.       MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
  203.       newnode = new_attrib_node( GL_EVAL_BIT );
  204.       newnode->data = attr;
  205.       newnode->next = head;
  206.       head = newnode;
  207.    }
  208.  
  209.    if (mask & GL_FOG_BIT) {
  210.       struct gl_fog_attrib *attr;
  211.       attr = MALLOC_STRUCT( gl_fog_attrib );
  212.       MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
  213.       newnode = new_attrib_node( GL_FOG_BIT );
  214.       newnode->data = attr;
  215.       newnode->next = head;
  216.       head = newnode;
  217.    }
  218.  
  219.    if (mask & GL_HINT_BIT) {
  220.       struct gl_hint_attrib *attr;
  221.       attr = MALLOC_STRUCT( gl_hint_attrib );
  222.       MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
  223.       newnode = new_attrib_node( GL_HINT_BIT );
  224.       newnode->data = attr;
  225.       newnode->next = head;
  226.       head = newnode;
  227.    }
  228.  
  229.    if (mask & GL_LIGHTING_BIT) {
  230.       struct gl_light_attrib *attr;
  231.       attr = MALLOC_STRUCT( gl_light_attrib );
  232.       MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
  233.       newnode = new_attrib_node( GL_LIGHTING_BIT );
  234.       newnode->data = attr;
  235.       newnode->next = head;
  236.       head = newnode;
  237.    }
  238.  
  239.    if (mask & GL_LINE_BIT) {
  240.       struct gl_line_attrib *attr;
  241.       attr = MALLOC_STRUCT( gl_line_attrib );
  242.       MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
  243.       newnode = new_attrib_node( GL_LINE_BIT );
  244.       newnode->data = attr;
  245.       newnode->next = head;
  246.       head = newnode;
  247.    }
  248.  
  249.    if (mask & GL_LIST_BIT) {
  250.       struct gl_list_attrib *attr;
  251.       attr = MALLOC_STRUCT( gl_list_attrib );
  252.       MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
  253.       newnode = new_attrib_node( GL_LIST_BIT );
  254.       newnode->data = attr;
  255.       newnode->next = head;
  256.       head = newnode;
  257.    }
  258.  
  259.    if (mask & GL_PIXEL_MODE_BIT) {
  260.       struct gl_pixel_attrib *attr;
  261.       attr = MALLOC_STRUCT( gl_pixel_attrib );
  262.       MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
  263.       newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
  264.       newnode->data = attr;
  265.       newnode->next = head;
  266.       head = newnode;
  267.    }
  268.  
  269.    if (mask & GL_POINT_BIT) {
  270.       struct gl_point_attrib *attr;
  271.       attr = MALLOC_STRUCT( gl_point_attrib );
  272.       MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
  273.       newnode = new_attrib_node( GL_POINT_BIT );
  274.       newnode->data = attr;
  275.       newnode->next = head;
  276.       head = newnode;
  277.    }
  278.  
  279.    if (mask & GL_POLYGON_BIT) {
  280.       struct gl_polygon_attrib *attr;
  281.       attr = MALLOC_STRUCT( gl_polygon_attrib );
  282.       MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
  283.       newnode = new_attrib_node( GL_POLYGON_BIT );
  284.       newnode->data = attr;
  285.       newnode->next = head;
  286.       head = newnode;
  287.    }
  288.  
  289.    if (mask & GL_POLYGON_STIPPLE_BIT) {
  290.       GLuint *stipple;
  291.       stipple = (GLuint *) malloc( 32*sizeof(GLuint) );
  292.       MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
  293.       newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
  294.       newnode->data = stipple;
  295.       newnode->next = head;
  296.       head = newnode;
  297.    }
  298.  
  299.    if (mask & GL_SCISSOR_BIT) {
  300.       struct gl_scissor_attrib *attr;
  301.       attr = MALLOC_STRUCT( gl_scissor_attrib );
  302.       MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
  303.       newnode = new_attrib_node( GL_SCISSOR_BIT );
  304.       newnode->data = attr;
  305.       newnode->next = head;
  306.       head = newnode;
  307.    }
  308.  
  309.    if (mask & GL_STENCIL_BUFFER_BIT) {
  310.       struct gl_stencil_attrib *attr;
  311.       attr = MALLOC_STRUCT( gl_stencil_attrib );
  312.       MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
  313.       newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
  314.       newnode->data = attr;
  315.       newnode->next = head;
  316.       head = newnode;
  317.    }
  318.  
  319.    if (mask & GL_TEXTURE_BIT) {
  320.       struct gl_texture_attrib *attr;
  321.  
  322.       /* save some special state info */
  323.       int texSet = ctx->Texture.CurrentSet;
  324.       int dim;
  325.       for (dim = 0; dim < 3; dim++) {
  326.          const struct gl_texture_object *obj;
  327.          if (dim == 0)
  328.             obj = ctx->Texture.Set[texSet].Current1D;
  329.          else if (dim == 1)
  330.             obj = ctx->Texture.Set[texSet].Current2D;
  331.          else if (dim == 2)
  332.             obj = ctx->Texture.Set[texSet].Current3D;
  333.          ctx->Texture.Priority[dim] = obj->Priority;
  334.          ctx->Texture.BorderColor[dim][0] = obj->BorderColor[0];
  335.          ctx->Texture.BorderColor[dim][1] = obj->BorderColor[1];
  336.          ctx->Texture.BorderColor[dim][2] = obj->BorderColor[2];
  337.          ctx->Texture.BorderColor[dim][3] = obj->BorderColor[3];
  338.          ctx->Texture.WrapS[dim] = obj->WrapS;
  339.          ctx->Texture.WrapT[dim] = obj->WrapT;
  340.          ctx->Texture.WrapR[dim] = obj->WrapR;
  341.          ctx->Texture.MinFilter[dim] = obj->MinFilter;
  342.          ctx->Texture.MagFilter[dim] = obj->MagFilter;
  343.       }
  344.  
  345.       attr = MALLOC_STRUCT( gl_texture_attrib );
  346.       MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
  347.       newnode = new_attrib_node( GL_TEXTURE_BIT );
  348.       newnode->data = attr;
  349.       newnode->next = head;
  350.       head = newnode;
  351.    }
  352.  
  353.    if (mask & GL_TRANSFORM_BIT) {
  354.       struct gl_transform_attrib *attr;
  355.       attr = MALLOC_STRUCT( gl_transform_attrib );
  356.       MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
  357.       newnode = new_attrib_node( GL_TRANSFORM_BIT );
  358.       newnode->data = attr;
  359.       newnode->next = head;
  360.       head = newnode;
  361.    }
  362.  
  363.    if (mask & GL_VIEWPORT_BIT) {
  364.       struct gl_viewport_attrib *attr;
  365.       attr = MALLOC_STRUCT( gl_viewport_attrib );
  366.       MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
  367.       newnode = new_attrib_node( GL_VIEWPORT_BIT );
  368.       newnode->data = attr;
  369.       newnode->next = head;
  370.       head = newnode;
  371.    }
  372.  
  373.    /* etc... */
  374.  
  375.    ctx->AttribStack[ctx->AttribStackDepth] = head;
  376.    ctx->AttribStackDepth++;
  377. }
  378.  
  379.  
  380.  
  381. void gl_PopAttrib( GLcontext* ctx )
  382. {
  383.    struct gl_attrib_node *attr, *next;
  384.    struct gl_enable_attrib *enable;
  385.    GLuint i, oldDrawBuffer;
  386.  
  387.    if (INSIDE_BEGIN_END(ctx)) {
  388.       gl_error( ctx, GL_INVALID_OPERATION, "glPopAttrib" );
  389.       return;
  390.    }
  391.  
  392.    if (ctx->AttribStackDepth==0) {
  393.       gl_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
  394.       return;
  395.    }
  396.  
  397.    ctx->AttribStackDepth--;
  398.    attr = ctx->AttribStack[ctx->AttribStackDepth];
  399.  
  400.    while (attr) {
  401.       switch (attr->kind) {
  402.          case GL_ACCUM_BUFFER_BIT:
  403.             MEMCPY( &ctx->Accum, attr->data, sizeof(struct gl_accum_attrib) );
  404.             break;
  405.          case GL_COLOR_BUFFER_BIT:
  406.         oldDrawBuffer = ctx->Color.DrawBuffer;
  407.             MEMCPY( &ctx->Color, attr->data,
  408.             sizeof(struct gl_colorbuffer_attrib) );
  409.         if (ctx->Color.DrawBuffer != oldDrawBuffer) {
  410.            gl_DrawBuffer(ctx, ctx->Color.DrawBuffer);
  411.             }
  412.             break;
  413.          case GL_CURRENT_BIT:
  414.             MEMCPY( &ctx->Current, attr->data,
  415.             sizeof(struct gl_current_attrib) );
  416.             break;
  417.          case GL_DEPTH_BUFFER_BIT:
  418.             MEMCPY( &ctx->Depth, attr->data,
  419.             sizeof(struct gl_depthbuffer_attrib) );
  420.             break;
  421.          case GL_ENABLE_BIT:
  422.             enable = (struct gl_enable_attrib *) attr->data;
  423.             ctx->Color.AlphaEnabled = enable->AlphaTest;
  424.             ctx->Transform.Normalize = enable->AutoNormal;
  425.             ctx->Color.BlendEnabled = enable->Blend;
  426.         for (i=0;i<MAX_CLIP_PLANES;i++) {
  427.                ctx->Transform.ClipEnabled[i] = enable->ClipPlane[i];
  428.         }
  429.         ctx->Light.ColorMaterialEnabled = enable->ColorMaterial;
  430.         ctx->Polygon.CullFlag = enable->CullFace;
  431.         ctx->Depth.Test = enable->DepthTest;
  432.         ctx->Color.DitherFlag = enable->Dither;
  433.         ctx->Fog.Enabled = enable->Fog;
  434.         ctx->Light.Enabled = enable->Lighting;
  435.         ctx->Line.SmoothFlag = enable->LineSmooth;
  436.         ctx->Line.StippleFlag = enable->LineStipple;
  437.         ctx->Color.IndexLogicOpEnabled = enable->IndexLogicOp;
  438.         ctx->Color.ColorLogicOpEnabled = enable->ColorLogicOp;
  439.         ctx->Eval.Map1Color4 = enable->Map1Color4;
  440.         ctx->Eval.Map1Index = enable->Map1Index;
  441.         ctx->Eval.Map1Normal = enable->Map1Normal;
  442.         ctx->Eval.Map1TextureCoord1 = enable->Map1TextureCoord1;
  443.         ctx->Eval.Map1TextureCoord2 = enable->Map1TextureCoord2;
  444.         ctx->Eval.Map1TextureCoord3 = enable->Map1TextureCoord3;
  445.         ctx->Eval.Map1TextureCoord4 = enable->Map1TextureCoord4;
  446.         ctx->Eval.Map1Vertex3 = enable->Map1Vertex3;
  447.         ctx->Eval.Map1Vertex4 = enable->Map1Vertex4;
  448.         ctx->Eval.Map2Color4 = enable->Map2Color4;
  449.         ctx->Eval.Map2Index = enable->Map2Index;
  450.         ctx->Eval.Map2Normal = enable->Map2Normal;
  451.         ctx->Eval.Map2TextureCoord1 = enable->Map2TextureCoord1;
  452.         ctx->Eval.Map2TextureCoord2 = enable->Map2TextureCoord2;
  453.         ctx->Eval.Map2TextureCoord3 = enable->Map2TextureCoord3;
  454.         ctx->Eval.Map2TextureCoord4 = enable->Map2TextureCoord4;
  455.         ctx->Eval.Map2Vertex3 = enable->Map2Vertex3;
  456.         ctx->Eval.Map2Vertex4 = enable->Map2Vertex4;
  457.         ctx->Transform.Normalize = enable->Normalize;
  458.         ctx->Transform.RescaleNormals = enable->RescaleNormals;
  459.         ctx->Point.SmoothFlag = enable->PointSmooth;
  460.         ctx->Polygon.OffsetPoint = enable->PolygonOffsetPoint;
  461.         ctx->Polygon.OffsetLine = enable->PolygonOffsetLine;
  462.         ctx->Polygon.OffsetFill = enable->PolygonOffsetFill;
  463.             ctx->Polygon.OffsetAny = ctx->Polygon.OffsetPoint ||
  464.                                      ctx->Polygon.OffsetLine ||
  465.                                      ctx->Polygon.OffsetFill;
  466.         ctx->Polygon.SmoothFlag = enable->PolygonSmooth;
  467.         ctx->Polygon.StippleFlag = enable->PolygonStipple;
  468.         ctx->Scissor.Enabled = enable->Scissor;
  469.         ctx->Stencil.Enabled = enable->Stencil;
  470.             ctx->Texture.Enabled = enable->Texture;
  471.             for (i=0; i<MAX_TEX_SETS; i++) {
  472.                ctx->Texture.Set[i].TexGenEnabled = enable->TexGen[i];
  473.             }
  474.             break;
  475.          case GL_EVAL_BIT:
  476.             MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
  477.             break;
  478.          case GL_FOG_BIT:
  479.             MEMCPY( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) );
  480.             break;
  481.          case GL_HINT_BIT:
  482.             MEMCPY( &ctx->Hint, attr->data, sizeof(struct gl_hint_attrib) );
  483.             break;
  484.          case GL_LIGHTING_BIT:
  485.             MEMCPY( &ctx->Light, attr->data, sizeof(struct gl_light_attrib) );
  486.             break;
  487.          case GL_LINE_BIT:
  488.             MEMCPY( &ctx->Line, attr->data, sizeof(struct gl_line_attrib) );
  489.             break;
  490.          case GL_LIST_BIT:
  491.             MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
  492.             break;
  493.          case GL_PIXEL_MODE_BIT:
  494.             MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
  495.             break;
  496.          case GL_POINT_BIT:
  497.             MEMCPY( &ctx->Point, attr->data, sizeof(struct gl_point_attrib) );
  498.             break;
  499.          case GL_POLYGON_BIT:
  500.             MEMCPY( &ctx->Polygon, attr->data,
  501.             sizeof(struct gl_polygon_attrib) );
  502.             break;
  503.      case GL_POLYGON_STIPPLE_BIT:
  504.         MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
  505.         break;
  506.          case GL_SCISSOR_BIT:
  507.             MEMCPY( &ctx->Scissor, attr->data,
  508.             sizeof(struct gl_scissor_attrib) );
  509.             break;
  510.          case GL_STENCIL_BUFFER_BIT:
  511.             MEMCPY( &ctx->Stencil, attr->data,
  512.             sizeof(struct gl_stencil_attrib) );
  513.             break;
  514.          case GL_TRANSFORM_BIT:
  515.             MEMCPY( &ctx->Transform, attr->data,
  516.             sizeof(struct gl_transform_attrib) );
  517.             break;
  518.          case GL_TEXTURE_BIT:
  519.             MEMCPY( &ctx->Texture, attr->data,
  520.             sizeof(struct gl_texture_attrib) );
  521.             /* Restore special texture state */
  522.             {
  523.                int texSet = ctx->Texture.CurrentSet;
  524.                int dim;
  525.                for (dim = 0; dim < 3; dim++) {
  526.                   struct gl_texture_object *obj;
  527.                   if (dim == 0)
  528.                      obj = ctx->Texture.Set[texSet].Current1D;
  529.                   else if (dim == 1)
  530.                      obj = ctx->Texture.Set[texSet].Current2D;
  531.                   else if (dim == 2)
  532.                      obj = ctx->Texture.Set[texSet].Current3D;
  533.                   obj->Priority = ctx->Texture.Priority[dim];
  534.                   obj->BorderColor[0] = ctx->Texture.BorderColor[dim][0];
  535.                   obj->BorderColor[1] = ctx->Texture.BorderColor[dim][1];
  536.                   obj->BorderColor[2] = ctx->Texture.BorderColor[dim][2];
  537.                   obj->BorderColor[3] = ctx->Texture.BorderColor[dim][3];
  538.                   obj->WrapS = ctx->Texture.WrapS[dim];
  539.                   obj->WrapT = ctx->Texture.WrapT[dim];
  540.                   obj->WrapR = ctx->Texture.WrapR[dim];
  541.                   obj->MinFilter = ctx->Texture.MinFilter[dim];
  542.                   obj->MagFilter = ctx->Texture.MagFilter[dim];
  543.                }
  544.             }
  545.             break;
  546.          case GL_VIEWPORT_BIT:
  547.             MEMCPY( &ctx->Viewport, attr->data,
  548.             sizeof(struct gl_viewport_attrib) );
  549.             if (ctx->Driver.Viewport) {
  550.                (*ctx->Driver.Viewport)( ctx, ctx->Viewport.X, ctx->Viewport.Y,
  551.                                   ctx->Viewport.Width, ctx->Viewport.Height );
  552.             }
  553.             if (ctx->Driver.DepthRange) {
  554.                (*ctx->Driver.DepthRange)( ctx, ctx->Viewport.Near,
  555.                                           ctx->Viewport.Far );
  556.             }
  557.             break;
  558.          default:
  559.             gl_problem( ctx, "Bad attrib flag in PopAttrib");
  560.             break;
  561.       }
  562.  
  563.       next = attr->next;
  564.       free( (void *) attr->data );
  565.       free( (void *) attr );
  566.       attr = next;
  567.    }
  568.  
  569.    ctx->NewState = NEW_ALL;
  570. }
  571.  
  572.  
  573. #define GL_CLIENT_PACK_BIT (1<<20)
  574. #define GL_CLIENT_UNPACK_BIT (1<<21)
  575.  
  576.  
  577. void gl_PushClientAttrib( GLcontext *ctx, GLbitfield mask )
  578. {
  579.    struct gl_attrib_node *newnode;
  580.    struct gl_attrib_node *head;
  581.  
  582.    if (INSIDE_BEGIN_END(ctx)) {
  583.       gl_error( ctx, GL_INVALID_OPERATION, "glPushClientAttrib" );
  584.       return;
  585.    }
  586.  
  587.    if (ctx->ClientAttribStackDepth>=MAX_CLIENT_ATTRIB_STACK_DEPTH) {
  588.       gl_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
  589.       return;
  590.    }
  591.  
  592.    /* Build linked list of attribute nodes which save all attribute */
  593.    /* groups specified by the mask. */
  594.    head = NULL;
  595.  
  596.    if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
  597.       struct gl_pixelstore_attrib *attr;
  598.       /* packing attribs */
  599.       attr = MALLOC_STRUCT( gl_pixelstore_attrib );
  600.       MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) );
  601.       newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
  602.       newnode->data = attr;
  603.       newnode->next = head;
  604.       head = newnode;
  605.       /* unpacking attribs */
  606.       attr = MALLOC_STRUCT( gl_pixelstore_attrib );
  607.       MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) );
  608.       newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
  609.       newnode->data = attr;
  610.       newnode->next = head;
  611.       head = newnode;
  612.    }
  613.    if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
  614.       struct gl_array_attrib *attr;
  615.       attr = MALLOC_STRUCT( gl_array_attrib );
  616.       MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
  617.       newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
  618.       newnode->data = attr;
  619.       newnode->next = head;
  620.       head = newnode;
  621.    }
  622.  
  623.    /* etc... */
  624.  
  625.    ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
  626.    ctx->ClientAttribStackDepth++;
  627. }
  628.  
  629.  
  630.  
  631.  
  632. void gl_PopClientAttrib( GLcontext *ctx )
  633. {
  634.    struct gl_attrib_node *attr, *next;
  635.  
  636.    if (INSIDE_BEGIN_END(ctx)) {
  637.       gl_error( ctx, GL_INVALID_OPERATION, "glPopClientAttrib" );
  638.       return;
  639.    }
  640.  
  641.    if (ctx->ClientAttribStackDepth==0) {
  642.       gl_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
  643.       return;
  644.    }
  645.  
  646.    ctx->ClientAttribStackDepth--;
  647.    attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
  648.  
  649.    while (attr) {
  650.       switch (attr->kind) {
  651.          case GL_CLIENT_PACK_BIT:
  652.             MEMCPY( &ctx->Pack, attr->data,
  653.                     sizeof(struct gl_pixelstore_attrib) );
  654.             break;
  655.          case GL_CLIENT_UNPACK_BIT:
  656.             MEMCPY( &ctx->Unpack, attr->data,
  657.                     sizeof(struct gl_pixelstore_attrib) );
  658.             break;
  659.          case GL_CLIENT_VERTEX_ARRAY_BIT:
  660.             MEMCPY( &ctx->Array, attr->data,
  661.             sizeof(struct gl_array_attrib) );
  662.             break;
  663.          default:
  664.             gl_problem( ctx, "Bad attrib flag in PopClientAttrib");
  665.             break;
  666.       }
  667.  
  668.       next = attr->next;
  669.       free( (void *) attr->data );
  670.       free( (void *) attr );
  671.       attr = next;
  672.    }
  673.  
  674.    ctx->NewState = NEW_ALL;
  675. }
  676.  
  677.